﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Creation;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.DB.Electrical;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.Revit;

namespace Assist
{
	public class RevitVersionFuncs
	{
		public static Color GetViewBackgroundColor(Application app)
		{
			Color backgroundColor = app.BackgroundColor;
			return Color.FromArgb((int)backgroundColor.Red, (int)backgroundColor.Green, (int)backgroundColor.Blue);
		}

		public static Color GetViewBackgroundReverseColor(Application app)
		{
			if (RevitVersionFuncs.GetViewBackgroundColor(app).ToArgb() == Color.Black.ToArgb())
			{
				return Color.White;
			}
			return Color.Black;
		}

		public static void SetFamilyMechanical(Document familyDoc)
		{
			Family ownerFamily = familyDoc.OwnerFamily;
			Category familyCategory = familyDoc.Settings.Categories[BuiltInCategory.OST_MechanicalEquipment];
			ownerFamily.FamilyCategory = familyCategory;
		}

		public static void SetVerticalOffsetDirectionOfText(ref XYZ inputDir)
		{
			inputDir = XYZ.BasisY;
		}

		public static ElementArray LineStyles(Document doc, CurveElement ce)
		{
			ElementArray elementArray = new ElementArray();
			foreach (ElementId elementId in ce.GetLineStyleIds())
			{
				Element element = doc.GetElement(elementId);
				elementArray.Append(element);
			}
			return elementArray;
		}

		public static DisplayUnitType GetDisplayUnitType(Document doc, UnitType ut)
		{
			return doc.GetUnits().GetFormatOptions(ut).DisplayUnits;
		}

		public static Type GetWallFoundation()
		{
			return typeof(WallFoundation);
		}

		public static List<GeometryObject> GetGeometryObjectArray(GeometryElement ge)
		{
			List<GeometryObject> list = new List<GeometryObject>();
			foreach (GeometryObject item in ge)
			{
				list.Add(item);
			}
			return list;
		}

		public static Element GetElement(Document doc, ElementId id)
		{
			return doc.GetElement(id);
		}

		public static Group NewGroup(Document doc, ElementSet eleSet)
		{
			List<ElementId> list = new List<ElementId>();
			foreach (object obj in eleSet)
			{
				Element element = (Element)obj;
				list.Add(element.Id);
			}
			return doc.Create.NewGroup(list);
		}

		public static AnnotationSymbol NewAnnotationSymbol(Document doc, XYZ origin, AnnotationSymbolType annotationSymbolType, View specView)
		{
			return doc.Create.NewFamilyInstance(origin, annotationSymbolType, specView) as AnnotationSymbol;
		}

		public static string GetWorksharingCentralFilename(Document doc)
		{
			string result = "";
			try
			{
				result = doc.GetWorksharingCentralModelPath().CentralServerPath;
			}
			catch
			{
			}
			return result;
		}

		public static Wall NewWall(Document doc, Curve curve, WallType wallType, Level level, double height, double offset, bool flip, bool structural)
		{
			return Wall.Create(doc, curve, wallType.Id, level.Id, height, offset, flip, structural);
		}

		public static Wall NewWall(Document doc, Curve curve, Level level, bool structural)
		{
			return Wall.Create(doc, curve, level.Id, structural);
		}

		public static View3D NewView3D(Document doc, XYZ direction)
		{
			ElementId view3dFamilyTypeId = RevitVersionFuncs.GetView3dFamilyTypeId(doc);
			if (null == view3dFamilyTypeId)
			{
				return null;
			}
			View3D view3D = View3D.CreateIsometric(doc, view3dFamilyTypeId);
			if (view3D != null)
			{
				XYZ xyz = direction * 10.0;
				XYZ xyz2 = new XYZ(direction.X, direction.Y, 0.0);
				XYZ xyz3;
				if (xyz2.IsAlmostEqualTo(XYZ.Zero))
				{
					xyz3 = XYZ.BasisY;
				}
				else
				{
					xyz2 = RevitVersionFuncs.RotateTo(xyz2, -Math.PI*.5, XYZ.BasisZ);
					xyz3 = RevitVersionFuncs.RotateTo(direction, Math.PI*.5, xyz2);
				}
				ViewOrientation3D orientation = new ViewOrientation3D(xyz, xyz3, direction);
				view3D.SetOrientation(orientation);
			}
			return view3D;
		}

		private static XYZ RotateTo(XYZ List, double angle, XYZ axis)
		{
			Transform transform = RevitVersionFuncs.CreateRotationAtPoint(axis, angle, new XYZ(0.0, 0.0, 0.0));
			return RevitVersionFuncs.TransformPoint(List, transform);
		}

		private static XYZ TransformPoint(XYZ point, Transform transform)
		{
			double x = point.X;
			double y = point.Y;
			double z = point.Z;
			XYZ xyz = transform.get_Basis(0);
			XYZ xyz2 = transform.get_Basis(1);
			XYZ xyz3 = transform.get_Basis(2);
			XYZ origin = transform.Origin;
			double num = x * xyz.X + y * xyz2.X + z * xyz3.X + origin.X;
			double num2 = x * xyz.Y + y * xyz2.Y + z * xyz3.Y + origin.Y;
			double num3 = x * xyz.Z + y * xyz2.Z + z * xyz3.Z + origin.Z;
			return new XYZ(num, num2, num3);
		}

		public static void HideElementSetInthe3dView(ElementSet elementSet, View3D view3d)
		{
			List<ElementId> list = new List<ElementId>();
			foreach (object obj in elementSet)
			{
				Element element = (Element)obj;
				list.Add(element.Id);
			}
			view3d.HideElements(list);
		}

		public static void ExportNavisworks(string folder, Document doc, ElementId viewId, string floorName)
		{
			doc.Export(folder, floorName, new NavisworksExportOptions
			{
				Coordinates = 1,
				ExportScope = 1,
				ViewId = viewId,
				Parameters = 2,
				DivideFileIntoLevels = true,
				ExportElementIds = true,
				ExportLinks = false,
				ExportParts = false,
				ExportRoomAsAttribute = true,
				ExportRoomGeometry = true,
				ExportUrls = true,
				FindMissingMaterials = true,
				ConvertElementProperties = false
			});
		}

		public static string GetSqlServerSystemDatabase()
		{
			return "System2016";
		}

		public static Plane GetPlaneWithSketchPlane(SketchPlane sPlane)
		{
			return sPlane.GetPlane();
		}

		public static Plane CreatePlanByNormalAndOrigin(XYZ normal, XYZ origin)
		{
			return new Plane(normal.Normalize(), origin);
		}

		public static Plane CreatePlanByOriginAndBasis(XYZ origin, XYZ basisX, XYZ baseY)
		{
			return new Plane(basisX.Normalize(), baseY.Normalize(), origin);
		}

		private static ElementId GetView3dFamilyTypeId(Document doc)
		{
			IEnumerable<ViewFamilyType> source = from elem in new FilteredElementCollector(doc).OfClass(typeof(ViewFamilyType)).ToElements()
			let theViewFamilyType = elem as Autodesk.Revit.DB.ViewFamilyType
			where theViewFamilyType.ViewFamily == 102
			select theViewFamilyType;
			if (source.First<ViewFamilyType>() == null)
			{
				return null;
			}
			return source.First<ViewFamilyType>().Id;
		}

		public static SketchPlane NewSketchPlane(FamilyItemFactory factory, Document doc, Plane plane)
		{
			return SketchPlane.Create(doc, plane);
		}

		public static List<Material> GetMaterials(Element element, Document document)
		{
			List<Material> list = new List<Material>();
			foreach (ElementId elementId in element.GetMaterialIds(false))
			{
				Material material = document.GetElement(elementId) as Material;
				if (material != null)
				{
					list.Add(material);
				}
			}
			return list;
		}

		public static SketchPlane NewSketchPlane(Document doc, Plane plane)
		{
			return SketchPlane.Create(doc, plane);
		}

		public static ViewPlan NewViewPlan(Document doc, string name, Level pLevel, ViewPlanType viewType)
		{
			FilteredElementCollector filteredElementCollector = new FilteredElementCollector(doc).OfClass(typeof(ViewFamilyType));
			ViewFamilyType viewFamilyType = null;
			foreach (Element element in filteredElementCollector)
			{
				ViewFamilyType viewFamilyType2 = element as Autodesk.Revit.DB.ViewFamilyType;
				if (viewFamilyType2 != null)
				{
					if (viewType == 1)
					{
						if (viewFamilyType2.ViewFamily == 109)
						{
							viewFamilyType = viewFamilyType2;
							break;
						}
					}
					else if (viewFamilyType2.ViewFamily == 111)
					{
						viewFamilyType = viewFamilyType2;
						break;
					}
				}
			}
			if (viewFamilyType == null)
			{
				return null;
			}
			ViewPlan viewPlan = ViewPlan.Create(doc, viewFamilyType.Id, pLevel.Id);
			viewPlan.Name = name;
			return viewPlan;
		}

		public static void Save(Document doc)
		{
			doc.Save();
		}

		public static void Save(Document doc, SaveOptions options)
		{
			doc.Save(options);
		}

		public static void SaveAs(Document doc, string filePath)
		{
			doc.SaveAs(filePath);
		}

		public static void SaveAs(Document doc, string filePath, SaveAsOptions options)
		{
			doc.SaveAs(filePath, options);
		}

		public static Transform CreateTranslation(XYZ vector)
		{
			return Transform.CreateTranslation(vector);
		}

		public static Transform CreateRotation(XYZ axis, double angle)
		{
			return Transform.CreateRotation(axis, angle);
		}

		public static Transform CreateRotationAtPoint(XYZ axis, double angle, XYZ origin)
		{
			return Transform.CreateRotationAtPoint(axis, angle, origin);
		}

		public static Curve CreateTransformed(Transform transform, Curve curve)
		{
			return curve.CreateTransformed(transform);
		}

		public static Transform CreateReflection(Plane plane)
		{
			return Transform.CreateReflection(plane);
		}

		public static ICollection<ElementId> CopyElements(Document sourceDocument, ICollection<ElementId> elementsToCopy, Document destinationDocument, Transform transform)
		{
			CopyPasteOptions copyPasteOptions = new CopyPasteOptions();
			copyPasteOptions.SetDuplicateTypeNamesHandler(new HideAndAcceptDuplicateTypeNamesHandler());
			return ElementTransformUtils.CopyElements(sourceDocument, elementsToCopy, destinationDocument, transform, copyPasteOptions);
		}

		public static ICollection<ElementId> CopyElements(View sourceView, ICollection<ElementId> elementsToCopy, View destinationView, Transform transform)
		{
			CopyPasteOptions copyPasteOptions = new CopyPasteOptions();
			copyPasteOptions.SetDuplicateTypeNamesHandler(new HideAndAcceptDuplicateTypeNamesHandler());
			return ElementTransformUtils.CopyElements(sourceView, elementsToCopy, destinationView, transform, copyPasteOptions);
		}

		public static void SetShowEdges(View view, bool showEdges)
		{
		}

		public static void FamilySymbolActivate(FamilySymbol familySymbol)
		{
			if (!familySymbol.IsActive)
			{
				familySymbol.Activate();
			}
		}

		public static FillPatternElement GetCutPatternWithMaterial(Material material, Document document)
		{
			ElementId cutPatternId = material.CutPatternId;
			return document.GetElement(cutPatternId) as FillPatternElement;
		}

		public static FillPatternElement GetSurfacePatternWithMaterial(Material material, Document document)
		{
			ElementId surfacePatternId = material.SurfacePatternId;
			return document.GetElement(surfacePatternId) as FillPatternElement;
		}

		public static void SetCutPattern(FillPatternElement fillPatternEle, ref Material material)
		{
			material.CutPatternId = fillPatternEle.Id;
		}

		public static void SetSurfacePattern(FillPatternElement fillPatternEle, ref Material material)
		{
			material.SurfacePatternId = fillPatternEle.Id;
		}

		public static RoomTag NewRoomTag(Document doc, Room room, UV point, View view)
		{
			return doc.Create.NewRoomTag(new LinkElementId(room.Id), point, view.Id);
		}

		public static IndependentTag NewTag(Document document, View dbview, Reference referenceToTag, bool addLeader, TagMode tagMode, TagOrientation tagOrientation, XYZ pnt)
		{
			Element element = document.GetElement(referenceToTag);
			return document.Create.NewTag(dbview, element, addLeader, tagMode, tagOrientation, pnt);
		}

		public static int SetRoomAreaBoundaryLocation(Settings settings, Document doc, int location)
		{
			AreaVolumeSettings areaVolumeSettings = AreaVolumeSettings.GetAreaVolumeSettings(doc);
			int spatialElementBoundaryLocation = areaVolumeSettings.GetSpatialElementBoundaryLocation(2);
			areaVolumeSettings.SetSpatialElementBoundaryLocation(location, 2);
			return spatialElementBoundaryLocation;
		}

		public static IList<ReferenceWithContext> FindReferencesWithContextByDirection(Document doc, XYZ pOrigin, XYZ pDirection, View3D pView)
		{
			new List<ReferenceWithContext>();
			return new ReferenceIntersector(new ElementClassFilter(typeof(Wall)), 16, pView).Find(pOrigin, pDirection);
		}

		public static Type GetBoundaryConditionsType()
		{
			return typeof(BoundaryConditions);
		}

		public static Category GetFamilyCategory(Family family)
		{
			return family.FamilyCategory;
		}

		public static List<XYZ> GetWireVertex(Wire wire)
		{
			List<XYZ> list = new List<XYZ>();
			int numberOfVertices = wire.NumberOfVertices;
			for (int i = 0; i < numberOfVertices; i++)
			{
				list.Add(wire.GetVertex(i));
			}
			return list;
		}

		public static List<Connector> GetWireConnectors(Wire wire)
		{
			List<Connector> list = new List<Connector>();
			ConnectorSetIterator connectorSetIterator = wire.ConnectorManager.Connectors.ForwardIterator();
			while (connectorSetIterator.MoveNext())
			{
				object obj = connectorSetIterator.Current;
				Connector connector = obj as Connector;
				if (connector.Domain == (Autodesk.Revit.DB.Domain)2)
				{
					list.Add(connector);
				}
			}
			return list;
		}

		public static List<Element> GetEquipmentByConnectors(List<Connector> connectorList)
		{
			List<Element> list = new List<Element>();
			foreach (Connector connector in connectorList)
			{
				ConnectorSet allRefs = connector.AllRefs;
				if (allRefs.Size > 0)
				{
					foreach (object obj in allRefs)
					{
						Element owner = ((Connector)obj).Owner;
						if (owner is FamilyInstance)
						{
							list.Add(owner);
						}
					}
				}
			}
			return list;
		}

		public static void GetWireConnectedEquipment(Wire wire, out Element startElement, out Element endElement)
		{
			startElement = null;
			endElement = null;
			List<Connector> wireConnectors = RevitVersionFuncs.GetWireConnectors(wire);
			if (wireConnectors.Count == 0)
			{
				return;
			}
			List<Element> equipmentByConnectors = RevitVersionFuncs.GetEquipmentByConnectors(wireConnectors);
			if (equipmentByConnectors.Count == 0)
			{
				return;
			}
			if (equipmentByConnectors.Count == 1)
			{
				XYZ point = (equipmentByConnectors[0].Location as LocationPoint).Point;
				using (List<Connector>.Enumerator enumerator = wireConnectors.GetEnumerator())
				{
					while (enumerator.MoveNext())
					{
						if (enumerator.Current.Origin.IsAlmostEqualTo(point))
						{
							startElement = equipmentByConnectors[0];
						}
						else
						{
							endElement = equipmentByConnectors[0];
						}
					}
				}
			}
			if (equipmentByConnectors.Count == 2)
			{
				XYZ endPoint = (wire.Location as LocationCurve).Curve.GetEndPoint(0);
				XYZ point2 = (equipmentByConnectors[0].Location as LocationPoint).Point;
				XYZ point3 = (equipmentByConnectors[1].Location as LocationPoint).Point;
				if (point2.DistanceTo(endPoint) < point3.DistanceTo(endPoint))
				{
					startElement = equipmentByConnectors[0];
					endElement = equipmentByConnectors[1];
					return;
				}
				startElement = equipmentByConnectors[1];
				endElement = equipmentByConnectors[0];
			}
		}

		public static Connector GetDeviceConnector(Element element)
		{
			Connector result = null;
			ConnectorSetIterator connectorSetIterator = (element as FamilyInstance).MEPModel.ConnectorManager.Connectors.ForwardIterator();
			while (connectorSetIterator.MoveNext())
			{
				object obj = connectorSetIterator.Current;
				Connector connector = obj as Connector;
				if (connector.Domain == (Autodesk.Revit.DB.Domain)2)
				{
					result = connector;
					break;
				}
			}
			return result;
		}

		public static void SetWire(Wire wire, List<XYZ> xyzList)
		{
			if (xyzList.Count > 2)
			{
				for (int i = 1; i < xyzList.Count - 1; i++)
				{
					wire.RemoveVertex(1);
				}
				for (int j = 1; j < xyzList.Count - 1; j++)
				{
					wire.InsertVertex(j, xyzList[j]);
				}
				new List<XYZ>();
				return;
			}
			if (xyzList.Count == 2)
			{
				Element element;
				Element element2;
				RevitVersionFuncs.GetWireConnectedEquipment(wire, out element, out element2);
				Connector connector = null;
				Connector connector2 = null;
				if (element != null)
				{
					connector = RevitVersionFuncs.GetDeviceConnector(element);
				}
				if (element2 != null)
				{
					connector2 = RevitVersionFuncs.GetDeviceConnector(element2);
				}
				Wire.Create(wire.Document, wire.GetTypeId(), wire.Document.ActiveView.Id, wire.WiringType, xyzList, connector, connector2);
				wire.Document.Delete(wire.Id);
			}
		}

		public static void ClearSelection(Selection selection)
		{
			selection.SetElementIds(new List<ElementId>());
		}

		public static void SetSelection(Selection selection, List<Element> selElements)
		{
			List<ElementId> list = new List<ElementId>();
			foreach (Element element in selElements)
			{
				list.Add(element.Id);
			}
			selection.SetElementIds(list);
		}

		public static void AddToSelection(Selection selection, Element element)
		{
			ICollection<ElementId> elementIds = selection.GetElementIds();
			elementIds.Add(element.Id);
			selection.SetElementIds(elementIds);
		}

		public static XYZ GetFaceFaceNormal(PlanarFace planarFace)
		{
			return planarFace.FaceNormal;
		}

		public static List<Curve> GetWireCurve(Wire wire, View view)
		{
			List<Curve> list = new List<Curve>();
			if (wire.WiringType == 1)
			{
				for (int i = 1; i < wire.NumberOfVertices; i++)
				{
					XYZ vertex = wire.GetVertex(i - 1);
					XYZ vertex2 = wire.GetVertex(i);
					Line item = Line.CreateBound(vertex, vertex2);
					list.Add(item);
				}
			}
			else
			{
				List<GeometryObject> geometryObjectArray = RevitVersionFuncs.GetGeometryObjectArray(wire.get_Geometry(new Options
				{
					View = view
				}));
				if (geometryObjectArray.Count > 0)
				{
					list.Add(geometryObjectArray[0] as NurbSpline);
				}
			}
			return list;
		}

		public static List<XYZ> GetChamferWireCtrlPoints(Document doc, Wire wire)
		{
			List<XYZ> list = new List<XYZ>();
			int numberOfVertices = wire.NumberOfVertices;
			for (int i = 0; i < numberOfVertices; i++)
			{
				list.Add(YJKRevitTools.SetZToZero(wire.GetVertex(i)));
			}
			return list;
		}

		public static void ConnectWires(Reference refer1, Reference refer2, Document doc)
		{
			string empty = string.Empty;
			Wire wire = doc.GetElement(refer1) as Wire;
			Wire wire2 = doc.GetElement(refer2) as Wire;
			XYZ globalPoint = YJKRevitTools.SetZToZero(refer1.GlobalPoint);
			XYZ globalPoint2 = YJKRevitTools.SetZToZero(refer2.GlobalPoint);
			View activeView = wire.Document.ActiveView;
			new List<XYZ>();
			new List<XYZ>();
			RevitVersionFuncs.GetChamferWireCtrlPoints(doc, wire);
			RevitVersionFuncs.GetChamferWireCtrlPoints(doc, wire2);
			if (!RevitVersionFuncs.ChangeWiresLocationCurve(ref wire, ref wire2, globalPoint, globalPoint2, ref empty))
			{
				YJKMessageBox.Information(empty);
				return;
			}
			RevitVersionFuncs.ConnectWire(wire, wire2);
		}

		public static void WireConnect(Reference ref1, Reference ref2, Document doc)
		{
			Wire wire = doc.GetElement(ref1) as Wire;
			Wire wire2 = doc.GetElement(ref2) as Wire;
			View activeView = wire.Document.ActiveView;
			List<XYZ> list = new List<XYZ>();
			List<XYZ> list2 = new List<XYZ>();
			list = RevitVersionFuncs.GetChamferWireCtrlPoints(wire.Document, wire);
			list2 = RevitVersionFuncs.GetChamferWireCtrlPoints(wire2.Document, wire2);
			double num = 10000000.0;
			int num2 = 0;
			int num3 = 0;
			for (int i = 0; i < list.Count; i++)
			{
				XYZ xyz = list[i];
				for (int j = 0; j < list2.Count; j++)
				{
					XYZ xyz2 = list2[j];
					if (xyz.DistanceTo(xyz2) < num)
					{
						num = xyz.DistanceTo(xyz2);
						num2 = i;
						num3 = j;
					}
				}
			}
			int index;
			if (num2 == 0)
			{
				index = num2 + 1;
			}
			else
			{
				index = num2 - 1;
			}
			int index2;
			if (num3 == 0)
			{
				index2 = num3 + 1;
			}
			else
			{
				index2 = num3 - 1;
			}
			Line line = Line.CreateBound(list[index], list[num2]);
			Line line2 = Line.CreateBound(list2[index2], list2[num3]);
			XYZ xyz3 = (line.GetEndPoint(1) - line.GetEndPoint(0)).Normalize();
			XYZ xyz4 = (line2.GetEndPoint(1) - line2.GetEndPoint(0)).Normalize();
			if (xyz3.IsAlmostEqualTo(xyz4) || xyz3.IsAlmostEqualTo(-xyz4))
			{
				XYZ endPoint = line.GetEndPoint(1);
				wire2.InsertVertex(num3, endPoint);
				wire2.RemoveVertex(num3 + 1);
				RevitVersionFuncs.ConnectWire(wire, wire2);
				return;
			}
			IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
			line2.Intersect(line, out intersectionResultArray);
			if (intersectionResultArray != null)
			{
				MessageBox.Show("选择的导线相交，请重新选择。", "盈建科提示");
				return;
			}
			Line line3 = Line.CreateUnbound(list[index], list[num2] - list[index]);
			Line.CreateUnbound(list2[index2], list2[num3] - list2[index2]).Intersect(line3, out intersectionResultArray);
			XYZ xyz5;
			if (intersectionResultArray != null)
			{
				xyz5 = intersectionResultArray.get_Item(0).XYZPoint;
				try
				{
					wire.InsertVertex(num2, xyz5);
					wire.RemoveVertex(num2 + 1);
				}
				catch
				{
				}
				try
				{
					wire2.InsertVertex(num3, xyz5);
					wire2.RemoveVertex(num3 + 1);
					goto IL_269;
				}
				catch
				{
					goto IL_269;
				}
			}
			xyz5 = list[num2];
			wire2.InsertVertex(num3, xyz5);
			wire2.RemoveVertex(num3 + 1);
			IL_269:
			RevitVersionFuncs.ConnectWire(wire, wire2);
		}

		private static bool ChangeWiresLocationCurve(ref Wire wire1, ref Wire wire2, XYZ globalPoint1, XYZ globalPoint2, ref string connMsg)
		{
			connMsg = string.Empty;
			List<XYZ> chamferWireCtrlPoints = RevitVersionFuncs.GetChamferWireCtrlPoints(wire1.Document, wire1);
			List<XYZ> chamferWireCtrlPoints2 = RevitVersionFuncs.GetChamferWireCtrlPoints(wire2.Document, wire2);
			XYZ intersectPointTwoWires = RevitVersionFuncs.GetIntersectPointTwoWires(chamferWireCtrlPoints, chamferWireCtrlPoints2);
			if (intersectPointTwoWires == null)
			{
				connMsg = "导线位置关系不合适！";
				return false;
			}
			connMsg = RevitVersionFuncs.ChangeWireCtrlPoints(ref wire1, globalPoint1, intersectPointTwoWires);
			if (string.IsNullOrEmpty(connMsg))
			{
				connMsg = RevitVersionFuncs.ChangeWireCtrlPoints(ref wire2, globalPoint2, intersectPointTwoWires);
			}
			wire1.Document.Regenerate();
			return string.IsNullOrEmpty(connMsg);
		}

		private static string ChangeWireCtrlPoints(ref Wire wire, XYZ pickPoint, XYZ intersectPoint)
		{
			string result = string.Empty;
			List<XYZ> chamferWireCtrlPoints = RevitVersionFuncs.GetChamferWireCtrlPoints(wire.Document, wire);
			int count = chamferWireCtrlPoints.Count;
			int pointPositionIndexOnWire = RevitVersionFuncs.GetPointPositionIndexOnWire(chamferWireCtrlPoints, pickPoint);
			int pointPositionIndexOnWire2 = RevitVersionFuncs.GetPointPositionIndexOnWire(chamferWireCtrlPoints, intersectPoint);
			if (pointPositionIndexOnWire2 == -1)
			{
				wire.InsertVertex(pointPositionIndexOnWire2 + 1, intersectPoint);
			}
			else if (pointPositionIndexOnWire2 == count - 1)
			{
				wire.InsertVertex(pointPositionIndexOnWire2, intersectPoint);
				wire.RemoveVertex(pointPositionIndexOnWire2 + 1);
			}
			else if (pointPositionIndexOnWire2 > -1 && pointPositionIndexOnWire2 < count - 1)
			{
				if (pointPositionIndexOnWire2 < pointPositionIndexOnWire)
				{
					RevitVersionFuncs.AddAndDeleteChamferPoints(ref wire, pointPositionIndexOnWire2, intersectPoint, false);
				}
				else if (pointPositionIndexOnWire2 == pointPositionIndexOnWire)
				{
					XYZ xyz = YJKRevitTools.SetZToZero(chamferWireCtrlPoints[pointPositionIndexOnWire]);
					double num = pickPoint.DistanceTo(xyz);
					double num2 = intersectPoint.DistanceTo(xyz);
					if (num <= num2)
					{
						result = RevitVersionFuncs.AddAndDeleteChamferPoints(ref wire, pointPositionIndexOnWire2, intersectPoint, true);
					}
					else
					{
						result = RevitVersionFuncs.AddAndDeleteChamferPoints(ref wire, pointPositionIndexOnWire2, intersectPoint, false);
					}
				}
				else
				{
					result = RevitVersionFuncs.AddAndDeleteChamferPoints(ref wire, pointPositionIndexOnWire2, intersectPoint, true);
				}
			}
			return result;
		}

		private static string AddAndDeleteChamferPoints(ref Wire wire, int insertIndex, XYZ insertPoint, bool beMax = true)
		{
			string result;
			try
			{
				List<XYZ> list = new List<XYZ>();
				if (beMax)
				{
					for (int i = 0; i <= insertIndex; i++)
					{
						list.Add(YJKRevitTools.SetZToZero(wire.GetVertex(i)));
					}
					list.Add(insertPoint);
				}
				else
				{
					list.Add(insertPoint);
					for (int j = insertIndex + 1; j < wire.NumberOfVertices - 1; j++)
					{
						list.Add(YJKRevitTools.SetZToZero(wire.GetVertex(j)));
					}
				}
				int k = 1;
				while (k < wire.NumberOfVertices - 1)
				{
					wire.RemoveVertex(k);
				}
				if (beMax)
				{
					for (int l = 1; l < list.Count; l++)
					{
						wire.InsertVertex(l, list[l]);
					}
					wire.RemoveVertex(list.Count);
				}
				else
				{
					for (int m = 0; m < list.Count; m++)
					{
						wire.InsertVertex(m + 1, list[m]);
					}
					wire.RemoveVertex(0);
				}
				wire.Document.Regenerate();
				result = string.Empty;
			}
			catch (Exception ex)
			{
				string message = ex.Message;
				result = "截取端导线已连接，不支持该情况连接操作！";
			}
			return result;
		}

		private static XYZ GetIntersectPointTwoWires(List<XYZ> wirePoints1, List<XYZ> wirePoints2)
		{
			XYZ result = null;
			if (wirePoints1 == null || wirePoints1.Count < 2 || wirePoints2 == null || wirePoints2.Count < 2)
			{
				return result;
			}
			if (wirePoints1.Count == 2 && wirePoints2.Count == 2)
			{
				result = RevitVersionFuncs.GetIntersectPointWiresTwoEndpoint(wirePoints1, wirePoints2);
			}
			else
			{
				result = RevitVersionFuncs.GetIntersectPointWiresMoreEndpoint(wirePoints1, wirePoints2);
			}
			return result;
		}

		private static XYZ GetIntersectPointWiresTwoEndpoint(List<XYZ> wirePoints1, List<XYZ> wirePoints2)
		{
			XYZ xyz = YJKRevitTools.SetZToZero(wirePoints1.First<XYZ>());
			XYZ xyz2 = YJKRevitTools.SetZToZero(wirePoints1.Last<XYZ>());
			YJKLine hyline = new YJKLine(xyz, xyz2);
			XYZ xyz3 = YJKRevitTools.SetZToZero(wirePoints2.First<XYZ>());
			XYZ xyz4 = YJKRevitTools.SetZToZero(wirePoints2.Last<XYZ>());
			YJKLine hyline2 = new YJKLine(xyz3, xyz4);
			XYZ result;
			if (hyline.IsLineOnLine(hyline2.Line))
			{
				XYZ xyz5 = (xyz.DistanceTo(xyz3) < xyz2.DistanceTo(xyz3)) ? xyz : xyz2;
				XYZ xyz6 = (xyz5.DistanceTo(xyz3) < xyz5.DistanceTo(xyz3)) ? xyz3 : xyz4;
				result = xyz5.Add(xyz6) / 2.0;
			}
			else
			{
				hyline.MakeUnBound();
				hyline2.MakeUnBound();
				result = hyline.IntersectionPoint(hyline2.Line);
			}
			return result;
		}

		private static XYZ GetIntersectPointWiresMoreEndpoint(List<XYZ> wirePoints1, List<XYZ> wirePoints2)
		{
			List<XYZ> list = new List<XYZ>();
			for (int i = 0; i < wirePoints1.Count - 1; i++)
			{
				YJKLine wireLineOnPlanFace = RevitVersionFuncs.GetWireLineOnPlanFace(wirePoints1[i], wirePoints1[i + 1]);
				for (int j = 0; j < wirePoints2.Count - 1; j++)
				{
					YJKLine wireLineOnPlanFace2 = RevitVersionFuncs.GetWireLineOnPlanFace(wirePoints2[j], wirePoints2[j + 1]);
					XYZ xyz = wireLineOnPlanFace.IntersectionPoint(wireLineOnPlanFace2.Line);
					if (xyz != null)
					{
						list.Add(xyz);
					}
				}
			}
			XYZ result;
			if (list.Count < 1)
			{
				result = RevitVersionFuncs.GetIntersectPointOnExtendLine(wirePoints1, wirePoints2);
			}
			else if (list.Count == 1)
			{
				result = list.First<XYZ>();
			}
			else
			{
				result = null;
			}
			return result;
		}

		private static XYZ GetIntersectPointOnExtendLine(List<XYZ> wirePoints1, List<XYZ> wirePoints2)
		{
			XYZ result = null;
			List<YJKLine> wireEndPointLines = RevitVersionFuncs.GetWireEndPointLines(wirePoints1);
			List<YJKLine> wireEndPointLines2 = RevitVersionFuncs.GetWireEndPointLines(wirePoints2);
			if (wireEndPointLines.Count < 1 || wireEndPointLines2.Count < 1)
			{
				return result;
			}
			if (wireEndPointLines.Count == 1 && wireEndPointLines2.Count == 1)
			{
				result = wireEndPointLines.First<YJKLine>().IntersectionPoint(wireEndPointLines2.First<YJKLine>().Line);
			}
			else
			{
				result = RevitVersionFuncs.GetIntersectPointTwoSpecialWireLines(wireEndPointLines, wireEndPointLines2);
			}
			return result;
		}

		private static XYZ GetIntersectPointTwoSpecialWireLines(List<YJKLine> firstWireLines, List<YJKLine> secondWireLines)
		{
			List<XYZ> list = new List<XYZ>();
			XYZ xyz;
			for (int i = 0; i < firstWireLines.Count; i++)
			{
				YJKLine hyline = firstWireLines[i];
				if (i == 0 || i == firstWireLines.Count - 1)
				{
					hyline.MakeUnBound();
				}
				for (int j = 0; j < secondWireLines.Count; j++)
				{
					YJKLine hyline2 = secondWireLines[j];
					if (j == 0 || j == secondWireLines.Count - 1)
					{
						hyline2.MakeUnBound();
					}
					xyz = hyline.IntersectionPoint(hyline2.Line);
					if (xyz != null && (firstWireLines.Count <= 1 || ((i != 0 || !hyline.IsPointOnLineExtension(xyz) || RevitVersionFuncs.CheckPointOnSpecEndPoint(hyline.StartPoint, hyline.EndPoint, xyz)) && (i != firstWireLines.Count - 1 || !hyline.IsPointOnLineExtension(xyz) || RevitVersionFuncs.CheckPointOnSpecEndPoint(hyline.EndPoint, hyline.StartPoint, xyz)))) && (secondWireLines.Count <= 1 || ((j != 0 || !hyline2.IsPointOnLineExtension(xyz) || RevitVersionFuncs.CheckPointOnSpecEndPoint(hyline2.StartPoint, hyline2.EndPoint, xyz)) && (j != secondWireLines.Count - 1 || !hyline2.IsPointOnLineExtension(xyz) || RevitVersionFuncs.CheckPointOnSpecEndPoint(hyline2.EndPoint, hyline2.StartPoint, xyz)))))
					{
						list.Add(xyz);
					}
				}
			}
			if (list.Count == 1)
			{
				xyz = list.First<XYZ>();
			}
			else
			{
				xyz = null;
			}
			return xyz;
		}

		private static bool CheckPointOnSpecEndPoint(XYZ firstPnt, XYZ endPnt, XYZ intersectPoint)
		{
			double num = firstPnt.DistanceTo(intersectPoint);
			double num2 = endPnt.DistanceTo(intersectPoint);
			return num < num2;
		}

		private static List<YJKLine> GetWireEndPointLines(List<XYZ> wirePoints)
		{
			List<YJKLine> list = new List<YJKLine>();
			if (wirePoints.Count >= 2)
			{
				for (int i = 0; i < wirePoints.Count - 1; i++)
				{
					list.Add(RevitVersionFuncs.GetWireLineOnPlanFace(wirePoints[i], wirePoints[i + 1]));
				}
			}
			return list;
		}

		private static YJKLine GetWireLineOnPlanFace(XYZ startPoint, XYZ endPoint)
		{
			return new YJKLine(YJKRevitTools.SetZToZero(startPoint), YJKRevitTools.SetZToZero(endPoint));
		}

		private static int GetPointPositionIndexOnWire(List<XYZ> wirePoints, XYZ insertionPoint)
		{
			if (wirePoints == null || wirePoints.Count < 2)
			{
				return -2;
			}
			insertionPoint = YJKRevitTools.SetZToZero(insertionPoint);
			int result = -1;
			double num = 0.001;
			int count = wirePoints.Count;
			for (int i = 0; i < count - 1; i++)
			{
				XYZ xyz = YJKRevitTools.SetZToZero(wirePoints[i]);
				if (xyz.IsAlmostEqualTo(insertionPoint, num))
				{
					result = i - 1;
					break;
				}
				XYZ xyz2 = YJKRevitTools.SetZToZero(wirePoints[i + 1]);
				if (xyz2.IsAlmostEqualTo(insertionPoint, num))
				{
					result = i;
					break;
				}
				YJKLine hyline = new YJKLine(xyz, xyz2);
				if (hyline.IsPointOnLine(insertionPoint))
				{
					result = i;
					break;
				}
				if (i == 0 && hyline.IsPointOnLineExtension(insertionPoint))
				{
					XYZ xyz3 = xyz.Subtract(insertionPoint).Normalize();
					XYZ xyz4 = xyz2.Subtract(xyz).Normalize();
					if (xyz3.IsAlmostEqualTo(xyz4, num))
					{
						result = i - 1;
						break;
					}
					if (hyline.IsPointOnLine(insertionPoint))
					{
						result = i;
						break;
					}
				}
				if (i == count - 2)
				{
					if (hyline.IsPointOnLineExtension(insertionPoint))
					{
						XYZ xyz5 = insertionPoint.Subtract(xyz2).Normalize();
						XYZ xyz6 = xyz2.Subtract(xyz).Normalize();
						if (xyz5.IsAlmostEqualTo(xyz6, num))
						{
							result = i + 1;
							break;
						}
					}
					else if (hyline.IsPointOnLine(insertionPoint))
					{
						result = i;
						break;
					}
				}
			}
			return result;
		}

		private static bool ConnectWire(Wire wire1, Wire wire2)
		{
			List<Connector> wireConnectors = RevitVersionFuncs.GetWireConnectors(wire1);
			List<Connector> wireConnectors2 = RevitVersionFuncs.GetWireConnectors(wire2);
			foreach (Connector connector in wireConnectors)
			{
				foreach (Connector connector2 in wireConnectors2)
				{
					XYZ origin = connector.Origin;
					XYZ origin2 = connector2.Origin;
					if (origin.DistanceTo(origin2) < 1E-05)
					{
						connector.ConnectTo(connector2);
						return true;
					}
				}
			}
			return false;
		}

		public static void GetDocumentFamilies(Dictionary<string, List<Family>> mapCatToFam, Document docForExport)
		{
			foreach (Family family in (from e in new FilteredElementCollector(docForExport).OfClass(typeof(Family)).WhereElementIsNotElementType()
			where ((Family)e).IsEditable && (((Family)e).FamilyCategory.Id.IntegerValue != -2000280 && ((Family)e).FamilyCategory.Id.IntegerValue != -2006020 && ((Family)e).FamilyCategory.Id.IntegerValue != -2000150 && ((Family)e).FamilyCategory.Id.IntegerValue != -2000263 && ((Family)e).FamilyCategory.Id.IntegerValue != -2006045 && ((Family)e).FamilyCategory.Id.IntegerValue != -2000400 && ((Family)e).FamilyCategory.Id.IntegerValue != -2002000 && ((Family)e).FamilyCategory.Id.IntegerValue != -2006040 && ((Family)e).FamilyCategory.Id.IntegerValue != -2000172 && ((Family)e).FamilyCategory.Id.IntegerValue != -2005027 && ((Family)e).FamilyCategory.Id.IntegerValue != -2000480 && ((Family)e).FamilyCategory.Id.IntegerValue != -2000170 && ((Family)e).FamilyCategory.Id.IntegerValue != -2005252 && ((Family)e).FamilyCategory.Id.IntegerValue != -2009021 && ((Family)e).FamilyCategory.Id.IntegerValue != -2005020 && ((Family)e).FamilyCategory.Id.IntegerValue != -2005130 && ((Family)e).FamilyCategory.Id.IntegerValue != -2005002 && ((Family)e).FamilyCategory.Id.IntegerValue != -2008129 && ((Family)e).FamilyCategory.Id.IntegerValue != -2008133 && ((Family)e).FamilyCategory.Id.IntegerValue != -2005025 && ((Family)e).FamilyCategory.Id.IntegerValue != -2008127 && ((Family)e).FamilyCategory.Id.IntegerValue != -2008004 && ((Family)e).FamilyCategory.Id.IntegerValue != -2005026 && ((Family)e).FamilyCategory.Id.IntegerValue != -2000133) && ((Family)e).FamilyCategory.Id.IntegerValue != -2001180
			select e).Cast<Family>().ToList<Family>())
			{
				if (mapCatToFam.ContainsKey(family.FamilyCategory.Name))
				{
					mapCatToFam[family.FamilyCategory.Name].Add(family);
				}
				else
				{
					List<Family> list = new List<Family>();
					list.Add(family);
					mapCatToFam.Add(family.FamilyCategory.Name, list);
				}
			}
		}

		public static double AddOffsetInVersion(int length = 6)
		{
			return 55.0;
		}

		public static List<XYZ> getWireVertexs(Wire wire)
		{
			List<XYZ> list = new List<XYZ>();
			int numberOfVertices = wire.NumberOfVertices;
			for (int i = 0; i < numberOfVertices; i++)
			{
				list.Add(wire.GetVertex(i));
			}
			return list;
		}

		public static void MirrorElements(Document document, ICollection<ElementId> elementsToMirror, Plane plane, bool mirrorCopies = true)
		{
			ElementTransformUtils.MirrorElements(document, elementsToMirror, plane, mirrorCopies);
		}

		public static Reference GetReference(ReferencePlane rPlane)
		{
			return rPlane.GetReference();
		}

		public static List<ElementId> MirrorElements(Document document, ICollection<ElementId> elementsToMirror, Plane plane, BuiltInCategory builtCategory, bool mirrorCopies = true)
		{
			new List<ElementId>();
			return ElementTransformUtils.MirrorElements(document, elementsToMirror, plane, mirrorCopies).ToList<ElementId>();
		}

		public static void SetFloatingRectangle(ref DockablePaneProviderData data, int left, int top, int right, int bottom)
		{
			data.InitialState.SetFloatingRectangle(new Rectangle(left, top, right, bottom));
		}

		public static Point GetRevitTopLeftPoint(ExternalCommandData cmdData)
		{
			Rectangle drawingAreaExtents = cmdData.Application.DrawingAreaExtents;
			return new System.Drawing.Point(drawingAreaExtents.Left, drawingAreaExtents.Top);
		}
	}
}
